


import * as d3 from 'd3'
import { useEffect, useRef } from 'react';
// import { Swatches } from "@d3/color-legend"
// import data from './data.json'
import getdata from './getdata';

function Demo0() {

    const chartRef = useRef();

    // 拖拽
    const drag = (simulation) => {

        function dragstarted(event, d) {
            if (!event.active) simulation.alphaTarget(0.3).restart();
            d.fx = d.x;
            d.fy = d.y;
        }

        function dragged(event, d) {
            d.fx = event.x;
            d.fy = event.y;
        }

        function dragended(event, d) {
            if (!event.active) simulation.alphaTarget(0);
            d.fx = null;
            d.fy = null;
        }

        return d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended);
    }
    // 
    function linkArc(d) {
        const r = Math.hypot(d.target.x - d.source.x, d.target.y - d.source.y);
        return `
          M${d.source.x},${d.source.y}
          A${r},${r} 0 0,1 ${d.target.x},${d.target.y}
        `;
    }
    const height = 600;
    const width = 600;

    useEffect(() => {
        async function init() {
            const data = await getdata()
            const links = data.links.map(d => Object.create(d));
            const nodes = data.nodes.map(d => Object.create(d));

            // const data = ({ nodes: Array.from(new Set(links.flatMap(l => [l.source, l.target])), id => ({ id })), links })


            const types = Array.from(new Set(links.map(d => d.type)));
            const color = d3.scaleOrdinal(types, d3.schemeCategory10);
            // Swatches(color)

            const simulation = d3.forceSimulation(nodes)
                .force("link", d3.forceLink(links).id(d => d.id))
                .force("charge", d3.forceManyBody().strength(-500))
                // .force('center', d3.forceCenter(width / 2, height / 2))
                .force("x", d3.forceX())
                .force("y", d3.forceY());

            let svg = d3
                .select(chartRef.current)
                .attr("viewBox", [-width / 2, -height / 2, width, height])
                .style("font", "12px sans-serif")
                .attr('width', width)
                .attr('height', height)
            // .attr('transform', 'translate(0,0)')

            // const svg = d3.create("svg")
            //     .attr("viewBox", [-width / 2, -height / 2, width, height])
            //     .style("font", "12px sans-serif");

            // Per-type markers, as they don't inherit styles.
            svg.append("defs")
                .selectAll("marker")
                .data(types)
                .join("marker")
                .attr("id", d => `arrow-${d}`)
                .attr("viewBox", "0 -5 10 10")
                .attr("refX", 15)
                .attr("refY", -0.5)
                .attr("markerWidth", 6)
                .attr("markerHeight", 6)
                .attr("orient", "auto")
                .append("path")
                .attr("fill", color)
                .attr("d", "M0,-5L10,0L0,5");

            // 线
            const link = svg.append("g")
                .attr("fill", "none")
                .attr("stroke-width", 1.5)
                .selectAll("path")
                .data(links)
                .join("path")
                .attr("stroke", d => color(d.type))
                .attr("marker-end", d => `url(${new URL(`#arrow-${d.type}`, window.location)})`);

            //节点
            const node = svg.append("g")
                .attr("fill", "currentColor")
                .attr("stroke-linecap", "round")
                .attr("stroke-linejoin", "round")
                .selectAll("g")
                .data(nodes)
                .join("g")
                .call(drag(simulation));

            // 节点图形
            node.append("circle")
                .attr("stroke", "white")
                .attr("stroke-width", 1.5)
                .attr("r", (d) => d.r)

            // 节点文字
            node.append("text")
                .attr("x", 8)
                .attr("y", "0.31em")
                .text(d => {

                    return d.id
                }) //文字内容
                .attr("color", "#000")
                .clone(true)
                .lower()
                .attr("fill", "none")
                .attr("stroke", "white")
                .attr("stroke-width", 30);

            simulation.on("tick", () => {
                link.attr("d", linkArc);
                node.attr("transform", d => `translate(${d.x},${d.y})`);
            });

            // invalidation.then(() => simulation.stop());

            // return svg.node();
        }
        init()
    }, [])

    return (
        <div className="force-chart--simple">
            <svg ref={chartRef} />
        </div>
    )

}

export default Demo0